package com.hy.config;


import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author huangziyan
 * @description TODO
 * @date 2020/12/3 11:23
 */
public class BeanFactory {
	/**
	 * ⼯⼚类的两个任务
	 * 任务⼀：加载解析xml，读取xml中的bean信息，通过反射技术实例化bean对象，然后放⼊
	 map待⽤
	 * 任务⼆：提供接⼝⽅法根据id从map中获取bean（静态⽅法）
	 */
	private static Map<String,Object> res = new HashMap<>(16);

	static {
		InputStream resourceAsStream = BeanFactory.class.getClassLoader().getResourceAsStream("user-config.xml");

		SAXReader reader = new SAXReader();
		try {
			Document document = reader.read(resourceAsStream);
			Element rootElement = document.getRootElement();
			List<Node> list = rootElement.selectNodes("//bean");
			for (int i = 0; i < list.size(); i++) {
				Element element = (Element) list.get(i);
				String id = element.attributeValue("id");
				String clazz = element.attributeValue("class");
				// 反射 实例化对象
				Class<?> aClass = Class.forName(clazz);
				Object o = aClass.newInstance();
				res.put(id,o);
			}
			// 维护bean之间的依赖关系
			List<Node> propertyNodes =
					rootElement.selectNodes("//property");

			for (int i = 0; i < propertyNodes.size(); i++) {
				Element element = (Element) propertyNodes.get(i);
				// 处理property元素
				String name = element.attributeValue("name");
				String ref = element.attributeValue("ref");
				String parentId =
						element.getParent().attributeValue("id");
				Object parentObject = res.get(parentId);
				//修改 TransferServlet
				//修改 TransferServiceImpl
				Method[] methods = parentObject.getClass().getMethods();
				for (int j = 0; j < methods.length; j++) {
					Method method = methods[j];
					if(("set" + name).equalsIgnoreCase(method.getName())){
						// bean之间的依赖关系（注⼊bean）
						Object propertyObject = res.get(ref);
						method.invoke(parentObject,propertyObject);
					}
				}
				// 维护依赖关系后重新将bean放⼊map中
				res.put(parentId,parentObject);
			}
		}catch (Exception e){
			e.printStackTrace();
		}

	}
	public static Object getBean(String id){
		return res.get(id);
	}

}
